require "claide"
require "pathname"
require "fileutils"
require "open3"

module Rpodupdate
  class Command < CLAide::Command
    prepend Config::Mixin
    class << self
      attr_accessor :should_clean_pods
      attr_accessor :should_clean_pod_cache
      attr_accessor :should_update_code
      attr_accessor :should_update_repo
      attr_accessor :should_clean_derived_data
      attr_accessor :is_dry_run
    end

    self.version = VERSION
    self.command = "rpodupdate"
    self.description = "快捷的pod update命令"

    def self.options
      [
        ["--silent", "Show nothing"],
        ["--mode=[common|manual]", "common mean than you input the ynnnnn, but manual need you input yourself"],
      ].concat(super)
    end

    self.arguments = [
      CLAide::Argument.new("--mode=[common|manual]", false),
    ]

    def self.run(argv)
      super(argv)
    end

    def initialize(argv)
      super(argv)
      config.silent = argv.flag?("silent", false)
      @mode = argv.option("mode", "common")
      @is_dry_run = "n"
    end

    def run
      if @mode == "common"
        @should_clean_pods = "y"
        @should_clean_pod_cache = "n"
        @should_update_code = "n"
        @should_update_repo = "n"
        @should_clean_derived_data = "n"
      else
        collectShouldCleanPods
        collectShouldCleanPodCache
        collectShouldUpdateCode
        collectShouldUpdateRepo
        collectShouldCleanDerivedData
      end

      UI.notice "正在执行pod update --verbose --no-repo-update --clean-install"
      treat_shouldCleanPods
      treat_collectShouldCleanPodCache
      treat_shouldUpdateCode
      treat_shouldUpdateRepo
      treat_shouldCleanDerivedData

      if @is_dry_run == "y"
        UI.notice "pod update --verbose --no-repo-update --clean-install"
      else
        UI.warning "is_dry_run == #{@is_dry_run}"
        cmd = "pod update --verbose --no-repo-update --clean-install"
        $stdout.sync = true
        Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
          stdout.each { |line| UI.pod_message line }
          return_value = wait_thr.value
        end
      end

      pods_path = FileUtils.pwd + "Pods"
      what_project = %x(ls -d *.xcodeproj)
      UI.warning "-------->#{what_project}"

      if @is_dry_run != "y" && @should_clean_pods == "y" && what_project == "DUApp.xcodeproj" && File.directory?(pods_path)
        UI.warning "==========>#{what_project}"
        %x{rm -rf ~/.cocoapods/du-Pods >/dev/null 2>/dev/null}
      end
      UI.warning "You are success"
      UI.warning "🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂🐂"
    end

    def treat_shouldCleanPods
      if @should_clean_pods == "y"
        UI.notice "\r正在删除Pods文件夹和Podfile.lock"
        if @is_dry_run == "y"
          UI.notice "rm -rf ./Pods"
          UI.notice "rm -rf ./Podfile.lock"
        else
          FileUtils.rm_rf(FileUtils.pwd + "Pods/")
          FileUtils.rm_rf(FileUtils.pwd + "Podfile.lock")
        end
      end
    end

    def treat_collectShouldCleanPodCache
      if @should_clean_pod_cache == "y"
        UI.notice "\r正在删除全部pod cache"
        if @is_dry_run == "y"
          UI.notice "pod cache clean --all"
        else
          %x(pod cache clean --all)
        end
      end
    end

    def treat_shouldUpdateCode
      if @should_update_code == "y"
        UI.notice "\r正在更新项目代码"
        current_branch = %x(git rev-parse --abbrev-ref HEAD)

        desc_msg = <<-fuckdesc
          #{"git stash"}
          #{"git pull origin #{current_branch} --tags"}
          #{"git stash pop"}
          #{"git branch --set-upstream-to=origin/#{current_branch} #{current_branch}"}
        fuckdesc

        if @is_dry_run == "y"
          UI.notice desc_msg
        else
          `git stash`
          `git pull origin #{current_branch} --tags`
          `git stash pop`
          `git branch --set-upstream-to=origin/#{current_branch} #{current_branch}`
        end
      end
    end

    def treat_shouldUpdateRepo
      if @should_update_repo == "y"
        UI.notice "\正在更新索引库"
        if @is_dry_run == "y"
          UI.notice "PodRepoUpdate"
        else
          %x(PodRepoUpdate)
        end
      end
    end

    def treat_shouldCleanDerivedData
      if @should_clean_derived_data == "y"
        UI.notice "\deleting DerivedData"
        if @is_dry_run == "y"
          UI.notice "rm -rf /Users/`whoami`/Library/Developer/Xcode/DerivedData"
        else
          %x{rm -rf /Users/`whoami`/Library/Developer/Xcode/DerivedData}
        end
      end
    end

    def collectShouldCleanPods
      printf "是否需要删除Pods文件夹和Podfile.lock(y/n):"
      @should_clean_pods = STDIN.gets.chomp.strip
      if @should_clean_pods.nil?
        collectShouldCleanPods
      elsif @should_clean_pods === "y" || @should_clean_pods === "n"
        @should_clean_pods
      else
        collectShouldCleanPods
      end
    end

    def collectShouldCleanPodCache
      printf "是否需要删除全部pod cache (y/n):"
      @should_clean_pod_cache = STDIN.gets.chomp.strip
      if @should_clean_pod_cache.nil?
        collectShouldCleanPodCache
      elsif @should_clean_pod_cache === "y" || @should_clean_pod_cache === "n"
        @should_clean_pod_cache
      else
        collectShouldCleanPodCache
      end
    end

    def collectShouldUpdateCode
      printf "是否需要拉取项目最新代码 (y/n):"
      @should_update_code = STDIN.gets.chomp.strip
      if @should_update_code.nil?
        collectShouldUpdateCode
      elsif @should_update_code === "y" || @should_update_code === "n"
        @should_update_code
      else
        collectShouldUpdateCode
      end
    end

    def collectShouldUpdateRepo
      printf "是否需要更新索引库 (y/n):"
      @should_update_repo = STDIN.gets.chomp.strip
      if @should_update_repo.nil?
        collectShouldUpdateRepo
      elsif @should_update_repo === "y" || @should_update_repo === "n"
        @should_update_repo
      else
        collectShouldUpdateRepo
      end
    end

    def collectShouldCleanDerivedData
      printf "是否需要删除DerivedData (y/n):"
      @should_clean_derived_data = STDIN.gets.chomp.strip
      if @should_clean_derived_data.nil?
        collectShouldCleanDerivedData
      elsif @should_clean_derived_data === "y" || @should_clean_derived_data === "n"
        @should_clean_derived_data
      else
        collectShouldCleanDerivedData
      end
    end
  end
end
